<?php

namespace App\Console\Commands;

use App\Library\Logic\OpenIdLogic;
use App\Library\Logic\ShopOrderLogic;
use App\Library\Logic\ShopUserLogic;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Model;

class TemplateMessageCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'command:templateMessage {type} {serialNumber}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';


    /**
     *
     * @return void
     * @throws GuzzleException
     *
     */
    public function handle(): void
    {
        if (!prod()) return;
        $type = $this->argument('type');
        $serialNumber = $this->argument('serialNumber');
        if (empty($serialNumber) || strlen($serialNumber) !== 20) return;
        else if (!in_array($type, __('template_type'))) return;
        $order = ShopOrderLogic::findBySerialNumber($serialNumber);
        if (is_null($order)) return;
        else if ($order->ext->status_pay !== 1) return;
        switch ($type) {
            case 'newOrder':
                $userMainId = $order->sellInfo->user_main_id > 0 ? $order->sellInfo->user_main_id : $order->sellInfo->user_id;
                $user = ShopUserLogic::query()->where([
                    'user_main_id' => $userMainId,
                    'user_peer_power' => 1
                ])->pluck('user_id')->toArray();
                $user[] = $userMainId;
                if (empty($user)) return;
                self::push($order, self::getOpenId($user), $type);
                break;
            case 'sqlError':
                $openId = __('template.openId');
                self::push($serialNumber, $openId, $type);
                break;
            default:
        }
    }

    private static function getOpenId(array $user): array
    {
        $openId = OpenIdLogic::query()
            ->where([
                'plateform' => 2,
                'type' => 'wx'
            ])
            ->whereIn('user_id', $user)->pluck('openid')->toArray();
        return array_unique($openId);
    }

    /**
     *
     * @param string|Model $data
     * @param array $openId
     * @param string $type
     * @return void
     * @throws GuzzleException
     */
    private static function push(string|Model $data, array $openId, string $type): void
    {
        foreach ($openId as $value) {
            if ($type === 'newOrder') self::httpPostData(self::newOrderPush($data, $value));
            else if($type === 'sqlError') self::httpPostData(self::sqlError($data, $value));
        }
    }

    private static function newOrderPush(Model $order, string $openId): array
    {
        return [
            'touser' => $openId,
            'template_id' => __('templates.newOrder'),
//            "miniprogram" => [
//                "appid" => __('wechat.miniapp.appId'),
//                "pagepath" => "/pagesB/order/sellOrderDetail?serialNumber=" . $order->serial_number
//            ],
            'data' => [
                'character_string1' => ['value' => $order->serial_number],
                'amount3' => ['value' => $order->order_total_price],
                'time5' => ['value' => $order->add_at],
            ]
        ];
    }

    private static function sqlError($data, $openId): array
    {
        return [
            'touser' => $openId,
            'template_id' => __('templates.sqlError'),
            'url' => 'http://8.146.200.81:8055/sqlError/' . $data,
            'data' => [
                'character_string2' => ['value' => $data],
                'time7' => ['value' => now()->toDateTimeString()],
            ]
        ];
    }

    /**
     *
     * @param $data
     * @return void
     * @throws GuzzleException
     *
     */
    static private function httpPostData($data): void
    {
        $url = sprintf(__('wechat.wx.url.step4'), wechatAccessToken('mp'));
        $client = new Client();
        $client->post($url, ['json' => $data])->getBody()->getContents();
    }
}
